home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TUT09NEW.ZIP / TUT9.CPP < prev    next >
Text File  |  1995-01-21  |  21KB  |  547 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. // TUTPROG9.CPP - VGA Trainer Program 9 (in Turbo C++ 3.0)                 //
  4. //                                                                         //
  5. // "The VGA Trainer Program" is written by Denthor of Asphyxia. However it //
  6. // was limited to only Pascal in its first run.  All I have done is taken  //
  7. // his original release, translated it to C++ and touched up a few things. //
  8. // I take absolutely no credit for the concepts presented in this code.    //
  9. //                                                                         //
  10. // Program Notes : This program demonstrates polygon moving and rotation.  //
  11. //                                                                         //
  12. //                 If you are compiling this program from within the       //
  13. //                 Turbo C++ environment, you must go under Options,       //
  14. //                 Debugger, and change the "Program Heap Size" to a value //
  15. //                 80 or greater.  If you are going to be fooling around   //
  16. //                 with the code a bit, I suggest raising this to about    //
  17. //                 100 just to be on the safe side.  You don't have to     //
  18. //                 worry about this if you are compiling command line.     //
  19. //                                                                         //
  20. //                 Just for reference, this is what I use:                 //
  21. //                                                                         //
  22. //                    tcc -mc -a -G -2 -O tut9.cpp                         //
  23. //                                                                         //
  24. //                 The way things are set up, there is no need to compile  //
  25. //                 or link tut9.cpp and gfx2.cpp seperately.               //
  26. //                                                                         //
  27. //                 The Compact memory model (-mc) seems to provide the     //
  28. //                 best results for this tutorial.  Remember, use this     //
  29. //                 memory model when you have little code (less than 64k)  //
  30. //                 and lots of data.                                       //
  31. //                                                                         //
  32. // Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
  33. // Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
  34. //                                                                         //
  35. // Last Modified : January 21, 1995                                        //
  36. //                                                                         //
  37. /////////////////////////////////////////////////////////////////////////////
  38.  
  39. //               //
  40. // INCLUDE FILES //
  41. //               //
  42.  
  43.   #include <conio.h>
  44.                              // clrscr(), getch(), kbhit()
  45.   #include <iostream.h>
  46.                              // cout()
  47.   #include <math.h>
  48.                              // sin(), cos()
  49.   #include <stdlib.h>
  50.                              // exit()
  51.   #include "gfx2.cpp"
  52.                              // our graphics library tools
  53.  
  54. //          //
  55. // TYPEDEFS //
  56. //          //
  57.  
  58.   typedef unsigned char byte;
  59.   typedef unsigned int  word;
  60.  
  61. //           //
  62. // CONSTANTS //
  63. //           //
  64.  
  65.   const MAXPOLYS   = 5;
  66.   const POLYPOINTS = 4;
  67.   const POLYCORDS  = 3;
  68.  
  69. //             //
  70. // LETTER DATA //
  71. //             //
  72.  
  73.   // The 3-D coordinates of our object ... stored as {X1,Y1,Z1},
  74.   // {X2,Y2,Z2} ... for the 4 points of a poly.
  75.   const int A[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  76.             { {{-10, 10, 0},{ -2,-10, 0},{ 0,-10, 0},{ -5,10, 0}},   // 1
  77.               {{ 10, 10, 0},{  2,-10, 0},{ 0,-10, 0},{  5,10, 0}},   // 2
  78.               {{ -2,-10, 0},{  2,-10, 0},{ 2, -5, 0},{ -2,-5, 0}},   // 3
  79.               {{ -6,  0, 0},{  6,  0, 0},{ 7,  5, 0},{ -7, 5, 0}},   // 4
  80.               {{  0,  0, 0},{  0,  0, 0},{ 0,  0, 0},{  0, 0, 0}} }; // 5
  81.  
  82.   //                             1----1    +    2----2
  83.   //                             |....|    |    |....|
  84.   //                             |....|    |    |....|
  85.   //                             `....`    |    '....'
  86.   //                              |....|   |   |....|
  87.   //                              `.4------+------4.'
  88.   //                               ||......|......||
  89.   //                               ``......|......''
  90.   //                                ||.....|.....||
  91.   //                                ||.....|.....||
  92.   //                      -------+---4+----+----+4---+-------
  93.   //                                 |...| | |...|
  94.   //                                 `...` | '...'
  95.   //                                  |...|||...|
  96.   //                                   |...|...|
  97.   //                                   |.3-+-3.|
  98.   //                                   `.|.|.|.'
  99.   //                                    ||.|.||
  100.   //                                    ||.|.||
  101.   //                                    `|.|.|'
  102.   //                                     3-2-3
  103.  
  104.   const int S[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  105.             { {{-10,-10, 0},{ 10,-10, 0},{10, -7, 0},{-10, -7, 0}},
  106.               {{-10, 10, 0},{ 10, 10, 0},{10,  7, 0},{-10,  7, 0}},
  107.               {{-10,  1, 0},{ 10,  1, 0},{10, -2, 0},{-10, -2, 0}},
  108.               {{-10, -8, 0},{ -7, -8, 0},{-7,  0, 0},{-10,  0, 0}},
  109.               {{ 10,  8, 0},{  7,  8, 0},{ 7,  0, 0},{ 10,  0, 0}} };
  110.  
  111.   const int P[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  112.             { {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
  113.               {{10,-10,0},{7,-10,0},{7,0,0},{10,0,0}},
  114.               {{-9,-10,0},{9,-10,0},{9,-7,0},{-9,-7,0}},
  115.               {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
  116.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} };
  117.  
  118.   const int H[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  119.             { {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
  120.               {{10,-10,0},{7,-10,0},{7,10,0},{10,10,0}},
  121.               {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
  122.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  123.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} };
  124.  
  125.   const int Y[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  126.             { {{-7,-10,0},{0,-3,0},{0,0,0},{-10,-7,0}},
  127.               {{7,-10,0},{0,-3,0},{0,0,0},{10,-7,0}},
  128.               {{-2,-3,0},{2,-3,0},{2,10,0},{-2,10,0}},
  129.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  130.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} };
  131.  
  132.   const int X[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  133.             { {{-7,-10,0},{10,7,0},{7,10,0},{-10,-7,0}},
  134.               {{7,-10,0},{-10,7,0},{-7,10,0},{10,-7,0}},
  135.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  136.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  137.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} };
  138.  
  139.   const int I[MAXPOLYS][POLYPOINTS][POLYCORDS] =
  140.             { {{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}},
  141.               {{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}},
  142.               {{-2,-9,0},{2,-9,0},{2,9,0},{-2,9,0}},
  143.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  144.               {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} };
  145.  
  146. //                     //
  147. // FUNCTION PROTOTYPES //
  148. //                     //
  149.  
  150.   void DrawPoly     (int x1, int y1, int x2, int y2,
  151.                      int x3, int y3, int x4, int y4,
  152.                      byte Col, word Where);
  153.   void SetUpPoints  ();
  154.   void RotatePoints (int X, int Y, int Z);
  155.   void DrawPoints   ();
  156.   void Whizz        (int sub, int °);
  157.   void MoveAround   ();
  158.  
  159. //            //
  160. // STRUCTURES //
  161. //            //
  162.  
  163.   // The data for every point we rotate
  164.   struct Point {
  165.     float x;
  166.     float y;
  167.     float z;
  168.   };
  169.  
  170. //                              //
  171. // GLOBAL VARIABLE DECLARATIONS //
  172. //                              //
  173.  
  174.   byte far *Virscr=NULL;           // Pointer to our virtual screen
  175.   word Vaddr;                      // Segment of our virtual screen
  176.   float Lookup[360][2];            // Our sin and cos lookup tables
  177.   int Xoff, Yoff, Zoff;            // Used for movement of the object
  178.   Point Lines[MAXPOLYS][4];        // The base object being rotated
  179.   Point Translated[MAXPOLYS][4];   // The rotated object
  180.  
  181.  
  182. ///////////////////////////////////////////////////////////////////////////////
  183. //                                                                           //
  184. //                                MAIN FUNCTION                              //
  185. //                                                                           //
  186. ///////////////////////////////////////////////////////////////////////////////
  187.  
  188. void main() {
  189.  
  190.   SetUpVirtual(Virscr,Vaddr);
  191.   // always check to see if enough memory was allocated
  192.   if (Virscr == NULL) {
  193.     SetText();
  194.     cout << "Insufficient memory for virtual screens, exiting...";
  195.     exit(1);
  196.   }
  197.  
  198.   clrscr();
  199.   cout
  200.     << "Hello there! Varsity has begun once again, so it is once again\n"
  201.     << "back to the grindstone ;-) ... anyway, this tutorial is, by\n"
  202.     << "popular demand, on poly-filling, in relation to 3-D solids.\n\n"
  203.     << "In this program, the letters of ASPHYXIA will fly past you. As you\n"
  204.     << "will see, they are solid, not wireframe. After the last letter has\n"
  205.     << "flown by, a large A will be left in the middle of the screen.\n\n"
  206.     << "You will be able to move it around the screen, and you will notice\n"
  207.     << "that it may have bits only half on the screen, i.e. clipping is\n"
  208.     << "perfomed. To control it use the following : ""A"" and ""Z"" control the Z\n"
  209.     << "movement, "","" and ""."" control the X movement, and ""S"" and ""X""\n"
  210.     << "control the Y movement. I have not included rotation control, but\n"
  211.     << "it should be easy enough to put in yourself ... if you have any\n"
  212.     << "hassles, leave me mail.\n\n";
  213.   cout << "Hit any key to continue ...\n";
  214.   getch();
  215.   SetMCGA();
  216.  
  217.   SetUpPoints();
  218.  
  219.   MoveAround();
  220.   SetText();
  221.  
  222.   ShutDown(Virscr);
  223.  
  224.   cout
  225.     << "All done. This concludes the ninth sample program in the ASPHYXIA\n"
  226.     << "Training series. You may reach DENTHOR under the names of GRANT\n"
  227.     << "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n"
  228.     << "Connectix BBS user, and occasionally read RSAProg.\n"
  229.     << "The numbers are available in the main text. You may also write to me at:\n"
  230.     << "             Grant Smith\n"
  231.     << "             P.O. Box 270\n"
  232.     << "             Kloof\n"
  233.     << "             3640\n"
  234.     << "I hope to hear from you soon!\n\n";
  235.   cout << "Hit any key to exit ...\n";
  236.   getch();
  237.  
  238. }
  239.  
  240.  
  241. /////////////////////////////////////////////////////////////////////////////
  242. //                                                                         //
  243. // DrawPoly() - This draws a polygon with 4 points at x1,y1, x2,y2, x3,y3, //
  244. //              x4,y4 in color Col at location Where                       //
  245. //                                                                         //
  246. /////////////////////////////////////////////////////////////////////////////
  247.  
  248. void DrawPoly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,
  249.               byte Col, word Where) {
  250.  
  251.   int x, mny, mxy, mnx, mxx, yc;
  252.   int mul1, div1, mul2, div2, mul3, div3, mul4, div4;
  253.  
  254.   // find the maximum y (mny) and minimum y (mny)
  255.               mny = y1;
  256.               mxy = y1;
  257.   if (y2<mny) mny = y2;
  258.   if (y2>mxy) mxy = y2;
  259.   if (y3<mny) mny = y3;
  260.   if (y3>mxy) mxy = y3;
  261.   if (y4<mny) mny = y4;
  262.   if (y4>mxy) mxy = y4;
  263.  
  264.   // if the mimimum or maximum is out of bounds, bring it back in
  265.   if (mny<  0) mny =   0;
  266.   if (mxy>199) mxy = 199;
  267.  
  268.   // verticle range checking
  269.   if (mny>199) return;
  270.   if (mxy<  0) return;
  271.  
  272.   // constants needed for intersection calculations
  273.   mul1 = x1-x4;  div1 = y1-y4;
  274.   mul2 = x2-x1;  div2 = y2-y1;
  275.   mul3 = x3-x2;  div3 = y3-y2;
  276.   mul4 = x4-x3;  div4 = y4-y3;
  277.  
  278.   for (yc=mny; yc<mxy; yc++) {
  279.     mnx = 320;
  280.     mxx =  -1;
  281.  
  282.     if ((y4 >= yc) || (y1 >= yc))
  283.       if ((y4 <= yc) || (y1 <= yc))
  284.         if (y4 != y1) {
  285.           x = ((yc-y4) * mul1 / div1) + x4;
  286.           if (x<mnx) mnx = x;
  287.           if (x>mxx) mxx = x;
  288.         }
  289.  
  290.     if ((y1 >= yc) || (y2 >= yc))
  291.       if ((y1 <= yc) || (y2 <= yc))
  292.         if (y1 != y2) {
  293.           x = ((yc-y1) * mul2 / div2) + x1;
  294.           if (x<mnx) mnx = x;
  295.           if (x>mxx) mxx = x;
  296.         }
  297.  
  298.     if ((y2 >= yc) || (y3 >= yc))
  299.       if ((y2 <= yc) || (y3 <= yc))
  300.         if (y2 != y3) {
  301.           x = ((yc-y2) * mul3 / div3) + x2;
  302.           if (x<mnx) mnx = x;
  303.           if (x>mxx) mxx = x;
  304.         }
  305.  
  306.     if ((y3 >= yc) || (y4 >= yc))
  307.       if ((y3 <= yc) || (y4 <= yc))
  308.         if (y3 != y4) {
  309.           x = ((yc-y3) * mul4 / div4) + x3;
  310.           if (x<mnx) mnx = x;
  311.           if (x>mxx) mxx = x;
  312.         }
  313.  
  314.     // horizontal range checking
  315.     if (mnx<  0)  mnx =   0;
  316.     if (mxx>319)  mxx = 319;
  317.  
  318.     if (mnx<=mxx)
  319.       // draw the horizontal line
  320.       Hline(mnx,mxx,yc,Col,Where);
  321.  
  322.   }
  323. }
  324.  
  325. /////////////////////////////////////////////////////////////////////////////
  326. //                                                                         //
  327. // SetUpPoints() - This creates the lookup table.                          //
  328. //                                                                         //
  329. /////////////////////////////////////////////////////////////////////////////
  330.  
  331. void SetUpPoints() {
  332.  
  333.   int loop1;
  334.  
  335.   // generate the sin() and cos() tables
  336.   for (loop1=0; loop1<360; loop1++) {
  337.     Lookup [loop1][0] = sin(rad(loop1));
  338.     Lookup [loop1][1] = cos(rad(loop1));
  339.   }
  340. }
  341.  
  342. /////////////////////////////////////////////////////////////////////////////
  343. //                                                                         //
  344. // RotatePoints() - This rotates object lines by X,Y and Z, then places    //
  345. //                  the result in Translated[]                             //
  346. //                                                                         //
  347. /////////////////////////////////////////////////////////////////////////////
  348.  
  349. void RotatePoints(int X, int Y, int Z) {
  350.  
  351.   int loop1, loop2;
  352.   Point temp;
  353.  
  354.   for (loop1=0; loop1<MAXPOLYS; loop1++) {
  355.     for (loop2=0; loop2<4; loop2++) {
  356.       temp.x = Lines[loop1][loop2].x;
  357.       temp.y = Lookup[X][1] * Lines[loop1][loop2].y - Lookup[X][0] * Lines[loop1][loop2].z;
  358.       temp.z = Lookup[X][0] * Lines[loop1][loop2].y + Lookup[X][1] * Lines[loop1][loop2].z;
  359.       Translated[loop1][loop2] = temp;
  360.  
  361.       if (Y>0) {
  362.         temp.x = Lookup[Y][1] * Translated[loop1][loop2].x - Lookup[Y][0] * Translated[loop1][loop2].y;
  363.         temp.y = Lookup[Y][0] * Translated[loop1][loop2].x + Lookup[Y][1] * Translated[loop1][loop2].y;
  364.         temp.z = Translated[loop1][loop2].z;
  365.         Translated[loop1][loop2] = temp;
  366.       }
  367.  
  368.       if (Z>0) {
  369.         temp.x = Lookup[Z][1] * Translated[loop1][loop2].x + Lookup[Z][0] * Translated[loop1][loop2].z;
  370.         temp.y = Translated[loop1][loop2].y;
  371.         temp.z = Lookup[Z][0] * Translated[loop1][loop2].x + Lookup[Z][1] * Translated[loop1][loop2].z;
  372.         Translated[loop1][loop2] = temp;
  373.       }
  374.     }
  375.   }
  376. }
  377.  
  378. /////////////////////////////////////////////////////////////////////////////
  379. //                                                                         //
  380. // DrawPoints() - This draws the translated object to the virtual screen.  //
  381. //                                                                         //
  382. /////////////////////////////////////////////////////////////////////////////
  383.  
  384. void DrawPoints() {
  385.  
  386.   int nx, ny, nx2, ny2, nx3, ny3, nx4, ny4, temp, loop1;
  387.  
  388.   for (loop1=0; loop1<MAXPOLYS; loop1++) {
  389.     if ((Translated[loop1][0].z+Zoff<0) && (Translated[loop1][1].z+Zoff<0) &&
  390.         (Translated[loop1][2].z+Zoff<0) && (Translated[loop1][4].z+Zoff<0)) {
  391.  
  392.       temp = Translated[loop1][0].z + Zoff;
  393.       nx   = ((256*Translated[loop1][0].x) / temp) + Xoff;
  394.       ny   = ((256*Translated[loop1][0].y) / temp) + Yoff;
  395.  
  396.       temp = Translated[loop1][1].z + Zoff;
  397.       nx2  = ((256*Translated[loop1][1].x) / temp) + Xoff;
  398.       ny2  = ((256*Translated[loop1][1].y) / temp) + Yoff;
  399.  
  400.       temp = Translated[loop1][2].z + Zoff;
  401.       nx3  = ((256*Translated[loop1][2].x) / temp) + Xoff;
  402.       ny3  = ((256*Translated[loop1][2].y) / temp) + Yoff;
  403.  
  404.       temp = Translated[loop1][3].z + Zoff;
  405.       nx4  = ((256*Translated[loop1][3].x) / temp) + Xoff;
  406.       ny4  = ((256*Translated[loop1][3].y) / temp) + Yoff;
  407.  
  408.       DrawPoly(nx,ny,nx2,ny2,nx3,ny3,nx4,ny4,13,Vaddr);
  409.     }
  410.   }
  411. }
  412.  
  413. /////////////////////////////////////////////////////////////////////////////
  414. //                                                                         //
  415. // Whizz() - This function moves the letters from one side of the screen   //
  416. //           to the other and also zooms them closer as they move.         //
  417. //                                                                         //
  418. /////////////////////////////////////////////////////////////////////////////
  419.  
  420. void Whizz(int sub, int °) {
  421.  
  422.   int loop1;
  423.  
  424.   for (loop1=(-64); loop1<(-4); loop1++) {
  425.  
  426.     Zoff = (loop1 * 8) - 15;
  427.     if (sub == 1) Xoff -= 7; else Xoff += 7;
  428.     RotatePoints(deg,deg,deg);
  429.     DrawPoints();
  430.     Flip(Vaddr,VGA);
  431.     Cls(0,Vaddr);
  432.     deg = (deg + 5) % 360;
  433.   }
  434. }
  435.  
  436. /////////////////////////////////////////////////////////////////////////////
  437. //                                                                         //
  438. // MoveAround() - This is the main display function.  First it brings the  //
  439. //                object towards the viewer by increasing the Zoff, then   //
  440. //                it passes control to the user.                           //
  441. //                                                                         //
  442. /////////////////////////////////////////////////////////////////////////////
  443.  
  444. void MoveAround() {
  445.  
  446.   int deg=0, loop1, loop2;
  447.   byte ch=1; // assign a dummy value to ch
  448.  
  449.   Yoff = 100;
  450.   Xoff = 350;
  451.   Cls(0,Vaddr);
  452.  
  453.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  454.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  455.       Lines[loop1][loop2].x = A[loop1][loop2][0];
  456.       Lines[loop1][loop2].y = A[loop1][loop2][1];
  457.       Lines[loop1][loop2].z = A[loop1][loop2][2];
  458.     }
  459.   Whizz(1,deg);
  460.  
  461.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  462.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  463.       Lines[loop1][loop2].x = S[loop1][loop2][0];
  464.       Lines[loop1][loop2].y = S[loop1][loop2][1];
  465.       Lines[loop1][loop2].z = S[loop1][loop2][2];
  466.     }
  467.   Whizz(0,deg);
  468.  
  469.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  470.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  471.       Lines[loop1][loop2].x = P[loop1][loop2][0];
  472.       Lines[loop1][loop2].y = P[loop1][loop2][1];
  473.       Lines[loop1][loop2].z = P[loop1][loop2][2];
  474.     }
  475.   Whizz(1,deg);
  476.  
  477.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  478.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  479.       Lines[loop1][loop2].x = H[loop1][loop2][0];
  480.       Lines[loop1][loop2].y = H[loop1][loop2][1];
  481.       Lines[loop1][loop2].z = H[loop1][loop2][2];
  482.     }
  483.   Whizz(0,deg);
  484.  
  485.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  486.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  487.       Lines[loop1][loop2].x = Y[loop1][loop2][0];
  488.       Lines[loop1][loop2].y = Y[loop1][loop2][1];
  489.       Lines[loop1][loop2].z = Y[loop1][loop2][2];
  490.     }
  491.   Whizz(1,deg);
  492.  
  493.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  494.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  495.       Lines[loop1][loop2].x = X[loop1][loop2][0];
  496.       Lines[loop1][loop2].y = X[loop1][loop2][1];
  497.       Lines[loop1][loop2].z = X[loop1][loop2][2];
  498.     }
  499.   Whizz(0,deg);
  500.  
  501.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  502.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  503.       Lines[loop1][loop2].x = I[loop1][loop2][0];
  504.       Lines[loop1][loop2].y = I[loop1][loop2][1];
  505.       Lines[loop1][loop2].z = I[loop1][loop2][2];
  506.     }
  507.   Whizz(1,deg);
  508.  
  509.   for (loop1=0; loop1<MAXPOLYS; loop1++)
  510.     for (loop2=0; loop2<POLYPOINTS; loop2++) {
  511.       Lines[loop1][loop2].x = A[loop1][loop2][0];
  512.       Lines[loop1][loop2].y = A[loop1][loop2][1];
  513.       Lines[loop1][loop2].z = A[loop1][loop2][2];
  514.     }
  515.   Whizz(0,deg);
  516.  
  517.   Cls(0,Vaddr);
  518.   Cls(0,VGA);
  519.  
  520.   Xoff = 160;
  521.  
  522.   do {
  523.     if (kbhit()) {
  524.       ch = getch();
  525.       switch (ch) {
  526.         case 'A': case 'a': Zoff += 5; break;  // away
  527.         case 'Z': case 'z': Zoff -= 5; break;  // toward
  528.         case ',':           Xoff -= 5; break;  // left
  529.         case '.':           Xoff += 5; break;  // right
  530.         case 'S': case 's': Yoff -= 5; break;  // down
  531.         case 'X': case 'x': Yoff += 5; break;  // up
  532.       }
  533.     }
  534.     DrawPoints();
  535.     Flip(Vaddr,VGA);
  536.     Cls(0,Vaddr);
  537.     RotatePoints(deg,deg,deg);
  538.     deg = (deg + 5) % 360;
  539.  
  540.     // if the key pressed above was 0 (i.e. a control character) then
  541.     // read the character code
  542.     if (ch == 0) ch = getch();
  543.  
  544.   } while (ch != 27); // if the escape code was 27 (escape key) then exit
  545.  
  546. }
  547.